
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


#include <netdb.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#include <cedule/log.h>
#include <cedule/debug.h>
#include <cedule/frame.h>

#include "config.h"
#include "client.h"

Client_t * client_create( Config_t * config ) 
{
	Client_t * result;

	result = (Client_t*) malloc (sizeof( Client_t ) );
	if ( !result )
		return NULL;

	result->fd = -1;
	result->config = config;

	return result;
}

int client_auth( Client_t * client ) {
	Frame_t * frame;
	frame = frame_create();
	int err;
	//auth = frame_auth_create();

	// request token
	frame->type = FRAME_TYPE_AUTH;
	frame->size = 0;
	frame->seq = 0;
	frame->ack = 0;
	// auth->type = FRAME_AUTH_TYPE_HELLO;

	err = frame_send( frame, client->fd );
	if (err ) goto error;

	/*
	// wait for token
	frame_reset( frame );	
	frame_recv( frame, client->fd );

	// send md5( login + password + token )
	frame->type = FRAME_TYPE_AUT
	frame_send( frame, cl
	*/
	return 0;

error:
	return -1;
}

int client_run( Client_t * client ) {

	char buffer[512];
	memset( buffer, 0, sizeof(buffer));
	/* envoie de donne et reception */
	Frame_t * frame;
	frame = frame_create();

	// initialize
	frame->type = FRAME_TYPE_AUTH;
	frame->size = 0;
	frame->seq = 2;
	frame->ack = 1;

	frame_send( frame, client->fd );

	//shutdown( client->fd, 2);
	//close( client->fd );

	return 0;
}

int client_connect( Client_t * client ) {
	struct sockaddr_in server_sock_addr;
	struct hostent *host_ent;
	long host_inet_addr = -1;
	//long status;

	bzero( &server_sock_addr, sizeof( server_sock_addr ) );
	host_inet_addr = inet_addr( client->config->host );

	/*
	   if ( (long) host_inet_addr != (long) -1 ) {
	   log_error( "using host_inet_addr" );
	   bcopy( &host_inet_addr, &server_sock_addr.sin_addr, sizeof(host_inet_addr) );
	   } else {
	   */

	host_ent = gethostbyname( client->config->host );
	if (host_ent == NULL) {
		log_error("Unable to get host name\n");
		return -1;
	}
	bcopy(host_ent->h_addr, &server_sock_addr.sin_addr,
			host_ent->h_length);
	/* } */
	server_sock_addr.sin_port = htons( client->config->port );
	server_sock_addr.sin_family = AF_INET;

	/* creation de la socket */
	if (( client->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		log_error( "Unable to create socket\n");
		goto error;
	}

	/* requete de connexion */
	if (connect( client->fd,
				(struct sockaddr *) &server_sock_addr,
				sizeof(server_sock_addr)) < 0) {
		log_error("Unable to connect\n");
		goto error;
	}


	return 0;

error:
	// reset client params
	client->fd = -1;
	return -1;
}
